home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 4
/
Apprentice-Release4.iso
/
Source Code
/
Libraries
/
Graphic Elements 3
/
GEQTHack
/
GEBalls.c
< prev
next >
Wrap
Text File
|
1995-06-13
|
4KB
|
192 lines
/*
GEBalls.c
Balls for GEQTHack
6/10/95
Al Evans
*/
#include "Rects.h"
#include "GEBalls.h"
#include "GESound.h"
short RangedRdm(short min, short max)
{
short rdm;
rdm = Random();
if (rdm < 0)
rdm = -rdm;
rdm = rdm % (max - min);
rdm += min;
return rdm;
}
void InitABall(GEWorldPtr world, GrafElPtr aBall)
{
// Target positions in pre-scaled world coordinates
short xPos = RangedRdm(ScaleToWorld(world, 4),
RectWidth(&world->animationRect) -
RectWidth(&aBall->animationRect) - ScaleToWorld(world, 4));
short yPos = RangedRdm(ScaleToWorld(world, 16),
RectHeight(&world->animationRect) -
RectHeight(&aBall->animationRect) - ScaleToWorld(world,16));
// Set Initial Position in absolute world coordinates
PtrMoveElementTo(world, aBall, xPos, yPos, false);
// Autochange proc
SetAutoChange(world, aBall->objectID, DoBallRandom, nil, 33);
// Movement speed kept in changeData
aBall->changeData = (Ptr) ((long) RangedRdm(1, 8) << 16) +
RangedRdm(1, 8);
// Collision proc
SetCollision(world, aBall->objectID, DoBallCollide, aBall->drawPlane);
}
Boolean InitBallGraphics(GEWorldPtr world)
{
GrafElPtr aBall;
short ballCount;
for (ballCount = 0; ballCount < numberOfBalls; ballCount++) {
// Make blue ball
aBall = NewAnimatedGraphic(world, firstBBID + ballCount,
blueBallPlane, rBlueBall, transparent, 0, 0, 2);
if (aBall == nil) return false;
InitABall(world, aBall);
// Make red ball
aBall = NewAnimatedGraphic(world, firstRBID + ballCount,
redBallPlane, rRedBall, transparent, 0, 0, 2);
if (aBall == nil) return false;
InitABall(world, aBall);
}
GEHoldSound((GESoundPtr) world->userData, rBallSnd, true);
return true;
}
GEDirection CheckLimits(Rect *objRect, Rect *limitRect)
{
if (objRect->right >= limitRect->right)
return right;
if (objRect->left <= limitRect->left)
return left;
if (objRect->top <= limitRect->top)
return up;
if (objRect->bottom >= limitRect->bottom)
return down;
return none;
}
void BounceObj(GEDirection direction, short *xMove, short *yMove)
{
switch (direction) {
case right:
if (*xMove > 0);
*xMove = -*xMove;
break;
case left:
if (*xMove < 0);
*xMove = -*xMove;
break;
case up:
if (*yMove < 0)
*yMove = -*yMove;
break;
case down:
if (*yMove > 0)
*yMove = -*yMove;
break;
}
}
pascal void DoBallRandom(GEWorldPtr world, GrafElPtr obj)
{
GEDirection collisionDir;
register short *currXMove = (short *) &obj->changeData + 1;
register short *currYMove = (short *) &obj->changeData;
collisionDir = CheckLimits(&obj->animationRect, &world->animationRect);
if (collisionDir != none)
BounceObj(collisionDir, currXMove, currYMove);
PtrMoveElement(world, obj, *currXMove, *currYMove);
}
pascal void DoBallCollide(GEWorldPtr world, GrafElPtr ball, GEDirection dir, CollisionPhase phase, GrafElPtr objHit)
{
register short *currXMove = (short *) &ball->changeData + 1;
register short *currYMove = (short *) &ball->changeData;
if (objHit->objectID != 'LOGO') { // Don't bounce off logo
switch (phase) {
case collisionBegin:
SetFrame(world, ball->objectID, 2);
GEScheduleSound((GESoundPtr) world->userData, rBallSnd, 1, 0);
break;
case collisionContinue:
switch (dir) {
case left:
if (*currXMove < 0)
*currXMove = -*currXMove;
break;
case right:
if (*currXMove > 0)
*currXMove = -*currXMove;
break;
case up:
if (*currYMove < 0)
*currYMove = -*currYMove;
break;
case down:
if (*currYMove > 0)
*currYMove = -*currYMove;
break;
case upLeft:
if (*currYMove < 0)
*currYMove = -*currYMove;
if (*currXMove < 0)
*currXMove = -*currXMove;
break;
case upRight:
if (*currYMove < 0)
*currYMove = -*currYMove;
if (*currXMove > 0)
*currXMove = -*currXMove;
break;
case downLeft:
if (*currYMove > 0)
*currYMove = -*currYMove;
if (*currXMove < 0)
*currXMove = -*currXMove;
break;
case downRight:
if (*currYMove > 0)
*currYMove = -*currYMove;
if (*currXMove > 0)
*currXMove = -*currXMove;
break;
}
break;
case collisionEnd:
SetFrame(world, ball->objectID, 1);
break;
}
}
}